<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>ComObjActive()</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link href="../css/default.css" rel="stylesheet" type="text/css">
</head>
<body>

<h1>ComObjActive() <span class="ver">[AHK_L 53+]</span></h1>

<p>检索已注册到 OLE 的正在运行的对象.</p>
<pre class="Syntax">ComObject := ComObjActive(CLSID)</pre>

<p id="param">创建表示作为参数或返回值传递的类型化值的对象.</p>
<pre class="Syntax">ParamObj := ComObjParameter(VarType, Value [, Flags])</pre>

<p id="missing">创建在调用 COM 对象的方法时可以用来代替可选参数默认值的对象.</p>
<pre class="Syntax">ParamObj := ComObjMissing()</pre>

<h4>高级</h4>
<p id="enwrap">包装或解开可用对象中的原始 <a href="http://msdn.microsoft.com/en-us/library/dd318520.aspx">IDispatch</a> 指针.</p>
<pre class="Syntax">ComObject := ComObjEnwrap(DispPtr)
DispPtr := ComObjUnwrap(ComObject)</pre>

<h3>参数</h3>
<table class="info">
  <tr>
    <td>CLSID</td>
    <td>要检索的 COM 对象的 CLSID 或可读 Prog ID.</td>
  </tr>
  <tr>
    <td>ComObject</td>
    <td>可以使用 <a href="../Objects.htm#Usage_Objects">对象语法</a> 的 COM 对象.</td>
  </tr>
  <tr>
    <td>VarType</td>
    <td>表示值类型的整数. 请参阅 <a href="ComObjType.htm#vt">ComObjType()</a> 了解类型列表.</td>
  </tr>
  <tr>
    <td>Value</td>
    <td>要包装的值. 当前仅支持整数值和指针值.</td>
  </tr>
  <tr>
    <td>Flags</td>
    <td>影响此函数和包装器对象行为的标志; 参见后面.</td>
  </tr>
  <tr>
    <td>DispPtr</td>
    <td>原始的 IDispatch 指针.</td>
  </tr>
</table>

<h3 id="Flags">Flags</h3>
<table class="info">
  <tr>
    <td>&nbsp;0&nbsp;</td>
    <td>默认行为. 为 IUnknown 和 IDispatch 指针自动调用 <a href="http://msdn.microsoft.com/en-us/library/ms691379.aspx">AddRef</a>, 所以调用者应该在适当时使用 <a href="ObjAddRef.htm">ObjRelease</a> 释放这些指针副本.</td>
  </tr>
  <tr>
    <td>&nbsp;1&nbsp;</td>
    <td>取得 IUnknown, IDispatch 或 SAFEARRAY 指针的所有权. 不调用 AddRef. 如果包装器对象包含 SAFEARRAY (VT_BYREF 除外), 那么当包装器对象被释放时会自动调用 <a href="http://msdn.microsoft.com/en-us/library/ms221702.aspx">SafeArrayDestroy</a>.</td>
  </tr>
</table>

<h3 id="Remarks">一般说明</h3>
<p>ComObjActive 是 <i>多态的</i>; 即任何名称以 "ComObj" 开始且不匹配其他某个 COM 函数的函数调用实际在调用 ComObjActive. 例如, <code>ComObj(9, DispPtr)</code> 和 <code>ComObjActive(DispPtr)</code> 都等同于 <code>ComObjEnwrap(DispPtr)</code>. 然而, 在未来的版本中此特性可能发生变化 (或实现了新的函数), 所以最好仅显示此页面中演示的形式, 此外 "ComObject" 可以用来代替 ComObjEnwrap 或 ComObjParameter.</p>
<p>当使用此函数包装或检索 IDispatch 或 IUnknown 接口指针时, 默认的行为会增加 COM 对象的引用数. 一般而言, 脚本中指针的原始副本被视为独立的引用, 当不再需要时必须在脚本中对其进行 <a href="ObjAddRef.htm">手动释放</a>. 释放包装器对象时, 也会同时释放其到 COM 对象的引用.</p>
<p><b>已知限制:</b> 每次包装 COM 对象时, 都会创建新的包装器对象. 比较和赋值运算中, 例如 <code>obj1 == obj2</code> 和 <code>array[obj1] := value</code>, 会把两个包装器对象视为唯一的, 即使它们包含相同的 COM 对象.</p>

<h3 id="Related">相关</h3>
<p><a href="ComObjCreate.htm">ComObjCreate</a>, <a href="ComObjGet.htm">ComObjGet</a>, <a href="ComObjConnect.htm">ComObjConnect</a>, <a href="ComObjError.htm">ComObjError</a>, <a href="ComObjFlags.htm">ComObjFlags</a>, <a href="ObjAddRef.htm">ObjAddRef/ObjRelease</a>, <a href="http://msdn.microsoft.com/en-us/library/ms221467.aspx">GetActiveObject (MSDN)</a></p>

<h3>示例</h3>
<p>ComObjUnwrap: 请参阅 <a href="ComObjConnect.htm#Examples">ComObjConnect</a>.</p>
<pre class="NoIndent" id="ByRefEx"><em>; 示例: 传递 VARIANT ByRef 到 COM 函数.</em>

code =
(
Sub Example(Var)
    MsgBox Var
    Var = "out value!"
End Sub
)
sc := <a href="ComObjCreate.htm">ComObjCreate</a>("ScriptControl"), sc.Language := "VBScript", sc.AddCode(code)

var := ComVar()
var[] := "in value"
sc.Run("Example", var.ref)
MsgBox % var[]

<em>; ComVar: 创建用来传递 ByRef 值的对象.
;   ComVar[] 检索值.
;   ComVar[] := Val 设置值.
;   ComVar.ref 检索 ByRef 对象用于传递到 COM 函数.</em>
ComVar(Type=0xC)
{
    static <a href="../Objects.htm#Extensibility">base</a> := { __Get: "ComVarGet", __Set: "ComVarSet", __Delete: "ComVarDel" }
    <em>; 创建含 1 个 VARIANT 类型变量的数组.  此方法可以让内部代码处理
    ; 在 VARIANT 和 AutoHotkey 内部类型之间的所有转换.</em>
    arr := <a href="ComObjArray.htm">ComObjArray</a>(Type, 1)
    <em>; 锁定数组并检索到 VARIANT 的指针.</em>
    DllCall("oleaut32\SafeArrayAccessData", "ptr", <a href="ComObjValue.htm">ComObjValue</a>(arr), "ptr*", arr_data)
    <em>; 保存可用于传递 VARIANT ByRef 的数组和对象.</em>
    return { ref: ComObjParameter(0x4000|Type, arr_data), _: arr, base: base }
}
ComVarGet(cv, <a href="../Functions.htm#Variadic">p*</a>) { <em>; 当脚本访问未知字段时调用.</em>
    if p.MaxIndex() = "" <em>; 没有名称/参数, 即 cv[]</em>
        return cv._[0]
}
ComVarSet(cv, v, p*) { <em>; 当脚本设置未知字段时调用.</em>
    if p.MaxIndex() = "" <em>; 没有名称/参数, 即 cv[]:=v</em>
        return cv._[0] := v
}
ComVarDel(cv) { <em>; 当对象被释放时调用.
    ; 必须进行这样的处理以释放内部数组.</em>
    DllCall("oleaut32\SafeArrayUnaccessData", "ptr", ComObjValue(cv._))
}

</pre>

</body>
</html>
